-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added AbortController polyfill #572
Conversation
Thanks for the suggestion! This looks like it simply pastes the other polyfill after ours. Could we instead keep the projects separate and instruct the users to compose the polyfills if they need abort functionality? |
I was concerned about the script order (which might be not really easy to maintain) as the fetch polyfill should always be before AbortController polyfill. Moreover abort controller is a part of fetch standard and it does not feel really good to me to separate its functionality into several polyfills. |
Sure, there is some convenience having the complete @mo @jimmywarting What do you think about this? |
@mislav don't you think that once abort signal is landed in browsers it will be strange not to see it in this polyfill |
I think that the abortable controller shouldn't be part of this fetch polyfill However I think this fetch polyfill should be able to handle a abort if a person send a AbortSignal in as an options and actually call The problem with this PR is that while it rejects and dose what it is suppose to do... It actually doesn't close the connection when the request is aborted (as mention in the readme.md) It's up to every promise based api to handle a AbortSignal. And when it comes to order of execution... AbortController should load before fetch. Personally i would close this PR (unless changed), the tests are grate but not the rest |
This is what I think should be implemented instead function abortError(){
var err;
try {
err = new DOMException('Aborted', 'AbortError');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
err = new Error('Aborted');
err.name = 'AbortError';
}
return err
}
// ...
return new Promise(function(resolve, reject) {
var request = new Request(input, init)
var xhr = new XMLHttpRequest()
if (request.signal) {
// Return early if already aborted, thus avoiding making an HTTP request
if (request.signal.aborted) {
return reject(abortError());
}
request.signal.addEventListener('abort', function () {
reject(abortError())
xhr.abort();
}, {once: true});
}
// rest of the xhr code
// ...
}) And also able to pass the signal into new request when cloning them if that is not taken care of... IMO i think the abortcontroller is wrong to even patch the fetch api, shouldn't even belong there |
@jimmywarting @mislav How should it behave in case when there is already a native fetch implementation, but it does not support AbortController? Ignore it and polyfill with XHR? |
The only way to abort a request today is by using xhr, You can't even use native fetch implementation. Firefox will be first to release it in there next version (v57) This code here should really only be implemented by a simple test to see if Request supports signal, that way it can patch native fetch and not doing it for a polyfill like this if it's dose what it's supposed to do eg: var controller = new AbortController();
var signal = controller.signal;
if (window.Request) {
var request = new Request('/', { signal });
if (!request.signal) {
// Native implementation don't support signal
// patch it only then
}
} |
While I very much appreciate the work is going on here, I would like to mention, that the proposed solution doesn't fully match the spec. Instead of actually aborting request, it just simulates the aborted response into the promise, but the request is being made. Rather than append the abortable part at the end of the file, I would suggest modifying the original fetch function. Moving change into the main part would give an access to the inner
|
@just-boris Pretty much what I have been saying already |
I've prepared an abortcontroller-polyfill branch based on @jimmywarting's patch that broke AbortSignal + AbortController out into a separate file so it can be imported without also getting a patched fetch(): https://github.com/mo/abortcontroller-polyfill/tree/break-out-abortcontroller/src I will only merge that to abortcontroller-polyfill master if it's useful for you; if you go in another direction I will leave abortcontroller-polyfill master as-is. |
The Abort feature is in the fetch spec. therefore I think that making it in another polyfill won't be the correct solution. https://developers.google.com/web/updates/2017/09/abortable-fetch |
@Attrash-Islam the fetch spec is only covering accepting an abort signal. Not how a abortcontroller is made. A abort controller can be used for so much more then just the fetch api. fetch api so just happens to be the first public usecase where an abort signal can actually take places in any native javascript function. Next time link to an actual spec and not to some blog post covering it's use cases. |
I attempted another pass at a resolution to #547 over in #592 based on some of the feedback here.
I'm curious to hear what others think of it! |
Abortable fetch requests are now supported after #592. Note that AbortController polyfill needs to be loaded separately in order for this to work in older browsers. |
Closes #547. Used polyfill from https://github.com/mo/abortcontroller-polyfill/. Tests included.